<template>
  <div @touchmove.stop.prevent class="c-w100 c-maxw640 c-p">
    <div @touchstart.capture="touchStart" @touchend.capture="touchEnd" class="c-bg-white c-pz100 c-w100 c-maxw640 c-pb10 box-br c-pt20" :class="positionClass">
      <div v-if="isShowAllDate" class="c-flex-row c-justify-sb c-aligni-center c-w100 c-hh60 c-pl30">
        <div class="c-fc-xblack c-fs28" @click="changeMonthStatus()">{{isChangeMonth == 0 ? showYears + '年' + currentMonths + '月' : isChangeMonth == 1 ? showYears + '年' : startYears + ' - ' + (startYears + 15)}}</div>
        <div v-if="isChangeMonth == 0" class="c-flex-row c-aligni-center c-fs22 c-fc-sblack">
          <div class="c-flex-row c-flex-center c-hh36 c-ww60 c-mr20 c-br20" @click="changeSelectType(0)" :class="selectType == 0 ? 'theme-bg c-fc-white' : 'c-bg-f2'">日</div>
          <div class="c-flex-row c-flex-center c-hh36 c-ww60 c-mr20 c-br20" @click="changeSelectType(1)" :class="selectType == 1 ? 'theme-bg c-fc-white' : 'c-bg-f2'">周</div>
          <div class="c-flex-row c-flex-center c-hh36 c-ww60 c-mr20 c-br20" @click="changeSelectType(2)" :class="selectType == 2 ? 'theme-bg c-fc-white' : 'c-bg-f2'">月</div>
          <div v-if="selectType == 0" @click="backToToday" class="c-ww100 c-hh42 back-today c-flex-row c-justify-center c-aligni-center">
            <div class="c-fs20 c-fc-white c-fw500">回到今日</div>
          </div>
        </div>
        <div v-if="isChangeMonth != 0" class="c-flex-row c-aligni-center">
          <div class="c-flex-row c-flex-center c-hh36 c-ww60 c-mr20 c-br20" @click="changeYears(0-Number(isChangeMonth))">
            <div class="iconfont c-fs20 c-fc-gray">&#xe712;</div>
          </div>
          <div class="c-flex-row c-flex-center c-hh36 c-ww60 c-br20" @click="changeYears(Number(isChangeMonth))">
            <div class="iconfont c-fs20 c-fc-gray">&#xe714;</div>
          </div>
        </div>
      </div>
      <div v-if="isChangeMonth == 1 && isShow" :class="isUp == 1 ? 'box_action_up' : ''" class="c-flex-row c-justify-center c-flexw-wrap c-w100 c-fc-xblack c-fs28">
        <div class="c-hh140 c-ww140 c-flex-row c-flex-center" @click="switchViewToMonth(showYears, i)" v-for="i in 16" :key="i">
          <div class="c-hh100 c-ww100 c-flex-row c-flex-center c-brp50" :class="i > 12 ? 'c-fc-gray' : currentYears == showYears && i == currentMonths ? 'theme-bg c-fc-white':''" >
            {{i % 12 == 0 ? 12 : i % 12}} 月
          </div>
        </div>
      </div>
      <div v-if="isChangeMonth == 2 && isShow" :class="isUp == 1 ? 'box_action_up' : ''" class="c-flex-row c-justify-center c-flexw-wrap c-w100 c-fc-xblack c-fs28">
        <div class="c-hh140 c-ww140 c-flex-row c-flex-center" @click="switchViewToMonth(showYears + i - 1, 0)" v-for="i in 16" :key="i">
          <div class="c-hh100 c-ww100 c-flex-row c-flex-center c-brp50" :class="startYears + i - 1 == currentYears ? 'theme-bg c-fc-white':''" >
            {{startYears + i - 1}}
          </div>
        </div>
      </div>
      <div v-if="isChangeMonth == 0" class="c-flex-row c-justify-sb c-aligni-center c-w100 c-ph10">
        <div class="c-ww80 c-hh60 c-fs24 c-fc-gray c-flex-row c-flex-center" v-for="i in 7" :key="i">{{weeksList[i-1]}}</div>
      </div>
      <div class="c-flex-row c-justify-sb c-aligni-center c-w100 c-ph10" v-if="isChangeMonth != 0 ? false : isShowAllDate ? true : index == currentWeek ? true : false" v-for="(item, index) in allDates" :key="index">
        <div class="c-ww80 c-hh60 c-fs24 c-flex-row c-flex-center c-p" :class="dItem.year == currentYears && dItem.month_str == currentMonths ? 'c-fc-xblack' : 'c-fc-gray'" v-for="(dItem, dIndex) in item" :key="dIndex">
          <div v-if="dItem.isMask != -1" style="font-size:12px;text-align:center;position:absolute;top:1px;right:5px;">
            <span style="display:inline-block;width:5px;height:5px;background-color:#1696ff;border-radius:50%;"></span>
          </div>
          <div class="c-ww40 c-hh40 c-flex-row c-flex-center" @click="selectDays(dItem, item, index)" :class="checkSelected(dItem.year, dItem.month_str, dItem.date, index) ? 'c-fc-white theme-bg c-brp50' : ''">{{currentDate == dItem.formatedDate ? '今' : dItem.date}}</div>
        </div>
      </div>
      <div class="c-w100 c-flex-row c-flex-center" @click="changeShowAllDate()">
        <div class="iconfont c-fs20 c-fc-gray">{{isShowAllDate ? '&#xe712;' : '&#xe714;'}}</div>
      </div>
      <inline-calendar :themeColor="$getThemeColor()" ref="calendar" v-show="false" @on-view-change="onViewChange"></inline-calendar>
    </div>
    <div class="masker c-fc-white" v-if="isShowAllDate && isShowCalendarGuide == 0" @click="closeGuide">
      <div class="c-flex-row c-justify-sb c-aligni-center c-ph30" :class="calendarGuideTop">
        <div class="iconfont c-fs80 c-rotate180">&#xe675;</div>
        <div class="iconfont c-fs80">&#xe6ed;</div>
        <div class="iconfont c-fs80">&#xe675;</div>
      </div>
      <div class="c-mt60 c-flex-row c-flex-center c-fs28 c-w100">可左右滑动查看日历</div>
    </div>
    <div class="masker-tran" v-if="isShowAllDate" @click="changeShowAllDate"></div>
  </div>
</template>

<script>
import { InlineCalendar } from 'ckjrweb-mp-ui/src/components/index'
export default {
  name: 'EduCalendar',
  components: {
    InlineCalendar,
  },
  props: {
    dateMasksList: { // 需要打点的日期列表
      type: Array,
      default: () => {
        return [];
      }
    },
    selectedDay: { // 跳转到特定日期
      type: String,
      default: ''
    },
    positionClass: {
      type: String,
      default: 'c-pf c-p-t0 c-box-shadowEdu'
    },
    calendarGuideTop: {
      type: String,
      default: 'c-mt190'
    },
  },
  beforeCreate() {
  },
  data() {
    return {
      theme: localStorage.getItem("colorName") ? localStorage.getItem("colorName") : "mb5_default",
      weeksList: ['日', '一', '二', '三', '四', '五', '六'], // 替换星期显示文字
      currentYears: '', // 当前年份
      showYears: '', // 展示的年份
      currentMonths: '', // 当前月份
      currentDate: '', // 当前日期
      allDates: [], // 选中月份的所有日期 6行
      currentWeek: 0, // 当前日期在本月的第几周
      isShowAllDate: false, // 是否显示当前月的所有日期
      selectDates: [], // 选中的所有日期
      selectType: 0, // 类型 0 按日 1按周 2按月份
      isChangeMonth: 0, // 是否选择月份 0 不显示 1显示月份 2显示年份
      startAllYears: Number(new Date().getFullYear()) - 100, // 可选的全部开始年份
      endAllYears: Number(new Date().getFullYear()) + 100, // 可选的全部结束年份
      startYears: Number(new Date().getFullYear()), // 可选的开始年份
      startY: 0,
      endY: 0,
      startX: 0,
      endX: 0,
      isShow: true,
      isUp: 0,
      monthEndDate: 0, // 本月几天
      isShowCalendarGuide: 0,
    }
  },
  created() {
  },
  mounted() {
    this.initData();
    let $this = this;
    this.$nextTick(() => {
      if ($this.$refs.calendar) {
        if ($this.selectedDay) {
          $this.switchViewToDate($this.selectedDay);
        } else {
          $this.$refs.calendar.switchViewToToday();
        }
      }
    })
  },
  watch: {
    dateMasksList(val) {
      if (val.length > 0) {
        this.setDateMasks();
      }
    },
    selectedDay(val) {
      if (val.length > 0) {
        this.switchViewToDate(val);
      }
    }
  },
  methods: {
    closeGuide() {
      this.isShowCalendarGuide = 1;
      localStorage.setItem('isShowCalendarGuide', 1);
    },
    backToToday() {
      let today = new Date();
      let data = {};
      let $this = this;
      $this.selectDates = [];
      this.$nextTick(() => {
        if ($this.$refs.calendar) {
          $this.$refs.calendar.switchViewToToday();
        }
      })
      this.selectDates = [];
      this.selectDates.push({
        year: today.getFullYear(),
        month: (today.getMonth() + 1),
        date: today.getDate()
      });
      data.startTime = this.formatDate(this.selectDates[0].year, this.selectDates[0].month, this.selectDates[0].date);
      data.endTime = this.formatDate(this.selectDates[0].year, this.selectDates[0].month, this.selectDates[0].date);
      data.days = this.monthEndDate; // 本月共几天
      this.$emit('getSelectDate', data);
    },
    initData() {
      this.currentYears = '';
      this.showYears = '';
      this.currentMonths = '';
      this.currentDate = new Date().getFullYear() + '-' + (Number(new Date().getMonth()) + 1 > 10 ? Number(new Date().getMonth()) + 1 : ('0' + Number(Number(new Date().getMonth()) + 1))) + '-' + (Number(new Date().getDate()) > 10 ? Number(new Date().getDate()) : ('0' + Number(new Date().getDate())));
      this.allDates = [];
      this.selectDates = [];
      this.currentWeek = 0;
      this.selectType = 0;
      this.isChangeMonth = 0;
      this.isShowAllDate = false;
      this.isShow = true;
      this.isUp = 0;
      this.startAllYears = Number(new Date().getFullYear()) - 100;
      this.endAllYears = Number(new Date().getFullYear()) + 100;
      this.startYears = Number(new Date().getFullYear());
      this.monthEndDate = 0;
      this.isShowCalendarGuide = localStorage.getItem('isShowCalendarGuide') ? localStorage.getItem('isShowCalendarGuide') : 0;
    },
    changeShowAllDate() {
      if (this.selectDates && this.selectDates.length > 0) {
        this.switchViewToMonth(this.selectDates[0].year, this.selectDates[0].month);
      }
      this.$nextTick(() => {
        this.isShowAllDate = !this.isShowAllDate;
        this.isChangeMonth = 0;
      })
    },
    touchStart(e) {
      this.startY = e.touches[0].clientY;
      this.startX = e.touches[0].clientX;
    },
    touchEnd(e) {
      this.endY = e.changedTouches[0].clientY;
      this.endX = e.changedTouches[0].clientX;
      if (e.touches.length < 2) {
        // 上下滑
        // if (this.startY - this.endY > 80) {
        //   this.nextMonths();
        // }
        // if (this.startY - this.endY < -80) {
        //   this.prevMonths();
        // }
        // 左右滑
        if (this.startX - this.endX > 80) {
          this.nextMonths();
        }
        if (this.startX - this.endX < -80) {
          this.prevMonths();
        }
      }
    },
    // 是否显示选择月份年份的弹窗
    changeMonthStatus() { // 0 不显示 1显示月份 2显示年份
      this.isUp = 0;
      if (this.isChangeMonth < 2) {
        this.isChangeMonth++;
      }
    },
    changeYears(type) { // type -1 前一年 1 后一年 type -2 前十六年 2 后十六年
      this.isShow = false;
      this.isUp = 1;
      if (type == -1 && this.currentYears > 1) {
        this.showYears--;
      } else if (type == 1) {
        this.showYears++;
      } else if (type == -2 && this.startYears >= (this.startAllYears - 16)) {
        this.startYears -= 16;
      } else if (type == 2 && this.startYears <= (this.endAllYears - 16)) {
        this.startYears += 16
      }
      this.$nextTick(() => {
        this.isShow = true;
      })
    },
    // 跳转到特定日期
    switchViewToDate(date) {
      this.switchViewToMonth(1990, 12)
      let year = Number(date.split('-')[0]);
      let month = Number(date.split('-')[1]);
      let day = Number(date.split('-')[2]);
      this.initData();
      this.selectDates.push({
        year: year,
        month: month,
        date: day
      })
      this.$nextTick(() => {
        this.switchViewToMonth(year, month);
      })
    },
    switchViewToMonth(currentYears, currentMonths) {
      if (currentMonths > 12) {
        return;
      }
      if (this.isChangeMonth == 2) {
        if (currentYears != this.currentYears) { // 如果切换年份，则月份也会清空，需要重新选择
          this.currentMonths = 0;
        }
        this.currentYears = currentYears;
        this.showYears = currentYears;
        this.isChangeMonth = 1;
      } else {
        this.currentYears = currentYears;
        this.showYears = currentYears;
        this.currentMonths = currentMonths;
        this.$refs.calendar.switchViewToMonth(this.currentYears, this.currentMonths);
        this.isChangeMonth = 0;
      }
    },
    prevMonths() {
      if (this.currentMonths == 1) {
        this.currentMonths = 12;
        this.currentYears = this.currentYears - 1;
        this.showYears = this.currentYears - 1;
      } else {
        this.currentMonths = this.currentMonths - 1
      }
      this.$refs.calendar.switchViewToMonth(this.currentYears, this.currentMonths)
    },
    nextMonths() {
      if (this.currentMonths == 12) {
        this.currentMonths = 1;
        this.currentYears = this.currentYears + 1;
        this.showYears = this.currentYears + 1;
      } else {
        this.currentMonths = this.currentMonths + 1
      }
      this.$refs.calendar.switchViewToMonth(this.currentYears, this.currentMonths)
    },
    formatDate(year, month, date, formatStr = '-') {
      month = month < 10 ? `0${month}` : month;
      date = date < 10 ? `0${date}` : date;
      return `${year}${formatStr}${month}${formatStr}${date}`;
    },
    // 选择日期
    selectDays(dItem, item, weekIndex) { // dItem一天的时间信息，item 一周的时间信息，allDates一个月
      let $this = this;
      let data = {};
      data.days = this.monthEndDate; // 本月共几天
      data.selectType = this.selectType
      this.isShowAllDate = false
      switch (this.selectType) { // selectType 0 按日 1按周 2按月份
        case 0:
          this.selectDates = [];
          // 跨月份或年份需要重新加载日历
          if (dItem.year != $this.currentYears || dItem.month_str != $this.currentMonths) {
            this.switchViewToMonth(dItem.year, dItem.month_str);
          } else {
            this.currentWeek = weekIndex;
          }
          this.selectDates.push({
            year: dItem.year,
            month: dItem.month_str,
            date: dItem.date
          });
          data.startTime = this.formatDate(this.selectDates[0].year, this.selectDates[0].month, this.selectDates[0].date);
          data.endTime = this.formatDate(this.selectDates[0].year, this.selectDates[0].month, this.selectDates[0].date);
          this.$emit('getSelectDate', data); // 选中日期后，重新获取选中日期的数据
          break;
        case 1:
          this.selectDates = [];
          this.currentWeek = 0;
          item.forEach((tItem, tIndex) => {
            $this.selectDates.push({
              year: tItem.year,
              month: tItem.month_str,
              date: tItem.date
            });
          })
          if (this.selectDates.length > 0) {
            this.currentWeek = weekIndex;
            let weekDateLength = this.selectDates.length - 1;
            data.startTime = this.formatDate(this.selectDates[0].year, this.selectDates[0].month, this.selectDates[0].date);
            data.endTime = this.formatDate(this.selectDates[weekDateLength].year, this.selectDates[weekDateLength].month, this.selectDates[weekDateLength].date);
            this.$emit('getSelectDate', data);
          }
          break;
        case 2:
          // 跨月份或年份需要重新加载日历
          if (dItem.year != $this.currentYears || dItem.month_str != $this.currentMonths) {
            this.switchViewToMonth(dItem.year, dItem.month_str);
            this.$nextTick(() => { // 等待日历重新渲染后，重新选择日期
              this.selectDays(dItem, item, weekIndex);
            })
            return;
          }
          this.selectDates = [];
          this.currentWeek = 0;
          this.allDates.forEach((mItem, mIndex) => {
            mItem.forEach((tItem, tIndex) => {
              if (tItem.year == $this.currentYears && tItem.month_str == $this.currentMonths) {
                $this.selectDates.push({
                  year: tItem.year,
                  month: tItem.month_str,
                  date: tItem.date
                });
              }
            })
          })
          this.currentWeek = weekIndex;
          let dateLength = this.selectDates.length - 1;
          data.startTime = this.formatDate(this.selectDates[0].year, this.selectDates[0].month, this.selectDates[0].date);
          data.endTime = this.formatDate(this.selectDates[dateLength].year, this.selectDates[dateLength].month, this.selectDates[dateLength].date);
          this.$emit('getSelectDate', data);
          break;
        default:
          break;
      }
    },
    // 当前日期是否选中
    checkSelected(year, month, date, weekIndex) {
      // 没有选中日期 || （非选中日期的年份 && 非选中日期月份 && 非按周选中类型）
      if (this.selectDates.length == 0 || ((year != this.selectDates[0].year || month != this.selectDates[0].month) && this.selectType != 1)) {
        return false;
      }
      switch (this.selectType) {
        case 0:
          if (date == this.selectDates[0].date) {
            this.currentWeek = weekIndex; // 选中日所在的行数（第几星期）
            return true;
          } else {
            return false;
          }
        case 1:
          // 本周的第一天是否是选中日期列表的第一天
          let isCompare = this.allDates[weekIndex][0].year == this.selectDates[0].year && this.allDates[weekIndex][0].month_str == this.selectDates[0].month && this.allDates[weekIndex][0].date == this.selectDates[0].date;
          if (this.currentWeek == weekIndex && isCompare) {
            return true;
          } else {
            return false;
          }
        case 2: // 前面已经控制，按月 && 非本年本月的日期都不会选中
          return true;
        default:
          break;
      }
    },
    // 切换日期选择类型
    changeSelectType(type) { // 0 按日 1按周 2按月份
      this.selectType = type;
      this.selectDates = [];
    },
    setDateMasks() {
      let $this = this;
      this.isChangeMonth = -1;
      this.allDates.forEach((item, index) => {
        item.forEach((dItem, dIndex) => {
          let isMask = -1;
          if ($this.dateMasksList.length > 0) {
            isMask = $this.dateMasksList.findIndex((mItem, mIndex) => {
              return mItem.year == dItem.year && mItem.month == dItem.month_str && mItem.date == dItem.date;
            })
          }
          $this.allDates[index][dIndex].isMask = isMask;
        })
      })
      this.$nextTick(() => {
        $this.isChangeMonth = 0;
      })
    },
    // 切换月份后触发
    onViewChange(val, count) {
      if (count > 0) { // 非初始化渲染，重新触发获取需要打点的日期
        this.$emit('getScheduleDate', val.firstCurrentMonthDate);
      }
      let $this = this;
      this.currentYears = val.year; // 当前渲染年份
      this.showYears = val.year;
      this.currentMonths = val.month; // 当前渲染月份
      this.allDates = [];
      this.allDates = val.allDates; // 当前渲染的所有日期信息 6 * 7 固定渲染6个星期
      let days = 0; // 本月共几天
      this.allDates.forEach((item, index) => {
        item.forEach((dItem, dIndex) => {
          if (dItem.year == val.year && dItem.month_str == val.month) { // 获取本月共几天
            days++;
          }
          if ($this.selectDates.length == 0 && dItem.isToday) { // 渲染月份为本月，默认选中今天
            $this.currentWeek = index; // 日历收起时展示第几个星期
            $this.currentDate = dItem.formatedDate;
            $this.selectDates.push({
              year: val.year,
              month: val.month,
              date: dItem.date,
            })
          } else if ($this.selectDates.length > 0 && $this.selectType == 0 && $this.selectDates[0].year == dItem.year && $this.selectDates[0].month == dItem.month_str && $this.selectDates[0].date == dItem.date) {
            $this.currentWeek = index;
          }
          let isMask = -1; // 当前日期是否需要打点 -1 不需要， 否则需要
          // dateMasksList 需要打点的日期列表 如果日期和当前渲染出来的日期相等，则isMask != -1,需要打点
          if ($this.dateMasksList.length > 0) {
            isMask = $this.dateMasksList.findIndex((mItem, mIndex) => {
              return mItem.year == dItem.year && mItem.month == dItem.month_str && mItem.date == dItem.date;
            })
          }
          $this.allDates[index][dIndex].isMask = isMask;
        })
      })
      this.monthEndDate = days; // 获取本月共几天
    },
  },
  activated() {
  },
  deactivated() {
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.box-br {
  border-radius: 0 0 0.75rem 0.75rem;
}
.masker {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  width: 100%;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.4);
}
.masker-tran {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  width: 100%;
  height: 87vh;
}
.box_action_up{
  animation: action_up 0.6s;
}
@keyframes action_up {
  0%{transform: scale(1);opacity: 1;}
  50%{ transform: scale(0.8);opacity: 0;}
  100%{transform: scale(1);opacity: 1;}
}
.back-today {
  background: linear-gradient(
    -90deg,
    rgba(248, 147, 92, 1),
    rgba(255, 109, 136, 1)
  );
  border-radius: 21px 0px 0px 21px;
}
</style>
